package com.wn.netty.sample;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/**
 * @FileName: MyChannelHandler
 * @Description: TODO
 * @Author: MaWenHao
 * @Created: 2020/7/28 - 17:17
 * @Version: V1.0
 * @Company: 东方微银科技（北京）有限公司
 */
public class MyServerChannelHandler extends ChannelInboundHandlerAdapter {

    /**
     * 接收消息方法
     *
     * @param ctx 上下文对象
     * @param msg 内容体
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 模拟耗时较长的操作(阻塞操作)
        // TimeUnit.SECONDS.sleep(10);

        // 异步处理任务
        ctx.channel().eventLoop().execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(10);
                System.out.println("休眠结束..........");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 异步定时任务
        ctx.channel().eventLoop().schedule(() -> System.out.println("异步定时任务结束.........."), 5L, TimeUnit.SECONDS);

        ByteBuf buf = (ByteBuf) msg;
        System.out.println("客户端发送的消息: " + buf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址: " + ctx.channel().remoteAddress());
    }

    /**
     * 应答方法
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 异步返回应答
        ctx.channel().eventLoop().execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(10);
                String message = "hello,客户端";
                ctx.writeAndFlush(Unpooled.copiedBuffer(message, CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 异常方法,释放资源
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
